(clear)

(deftemplate persona
(slot nombre)
(slot sexo (allowed-values hombre mujer))
(slot padre)
(slot madre)
(slot conyuge)
(multislot hijos)
(multislot hermanos)
(multislot tios)
(multislot abuelos (cardinality 0 2))
(multislot nietos)
)

(deffacts initial-fact
    (persona (nombre Juan) (sexo hombre) (hijos Carlos Mateo Clara) (conyuge Sofia))
    (persona (nombre Sofia) (sexo mujer) (hijos Carlos Mateo Clara) (conyuge Juan))
    (persona (nombre Carlos) (sexo hombre) (padre Juan) (madre Sofia))
    (persona (nombre Mateo) (sexo mujer) (padre Juan) (madre Sofia) (conyuge Calixta)(hijos Amancio Amanda))
    (persona (nombre Calixta) (sexo mujer) (conyuge Mateo) (hijos Amancio Amanda))
    (persona (nombre Clara) (sexo mujer) (padre Juan) (madre Sofia) (conyuge Joao) (hijos Pepito Julia))
    (persona (nombre Joao) (sexo hombre) (conyuge Clara) (hijos Pepito Julia))
    (persona (nombre Amancio) (sexo hombre) (padre Mateo) (madre Calixta))
    (persona (nombre Amanda) (sexo mujer) (padre Mateo) (madre Calixta))
    (persona (nombre Pepito) (sexo hombre) (padre Joao) (madre Clara))   
    (persona (nombre Julia) (sexo mujer) (padre Joao) (madre Clara) (conyuge Mario) (hijos Julieta Juanete))
    (persona (nombre Mario) (sexo hombre) (conyuge Julia) (hijos Julieta Juanete))
    (persona (nombre Julieta) (sexo mujer) (padre Mario) (madre Julia))   
    (persona (nombre Juanete) (sexo hombre) (padre Mario) (madre Julia))   
)

(defrule abuelo_materno
    ?elNieto  <- (persona (nombre ?n) (madre ?p) (abuelos $?losAbuelos))
    (persona (nombre ?p) (padre ?a))
    ?elAbuelo <- (persona (nombre ?a) (nietos $?losNietos))
    =>
    (bind ?pos (member$ ?n $?losNietos))
    (if (not ?pos) then
        (bind $?losNietos (insert$ $?losNietos (+(length$ $?losNietos) 1) ?n))
        (modify ?elAbuelo (nietos $?losNietos))
        (printout t "Ahora, los nietos de " ?a " son " $?losNietos crlf)
    )
    (bind ?pos (member$ ?a $?losAbuelos))
    (if (not ?pos) then
        (bind $?losAbuelos (insert$ $?losAbuelos (+(length$ $?losAbuelos) 1) ?a))
        (modify ?elNieto (abuelos $?losAbuelos))
        (printout t "Ahora, los abuelos de " ?n " son " $?losAbuelos crlf)
    )
)

(defrule abuela_materna
    ?elNieto  <- (persona (nombre ?n) (madre ?p) (abuelos $?losAbuelos))
    (persona (nombre ?p) (madre ?a))
    ?elAbuelo <- (persona (nombre ?a) (nietos $?losNietos))
    =>
    (bind ?pos (member$ ?n $?losNietos))
    (if (not ?pos) then
        (bind $?losNietos (insert$ $?losNietos (+(length$ $?losNietos) 1) ?n))
        (modify ?elAbuelo (nietos $?losNietos))
        (printout t "Ahora, los nietos de " ?a " son " $?losNietos crlf)
    )
    (bind ?pos (member$ ?a $?losAbuelos))
    (if (not ?pos) then
        (bind $?losAbuelos (insert$ $?losAbuelos (+(length$ $?losAbuelos) 1) ?a))
        (modify ?elNieto (abuelos $?losAbuelos))
        (printout t "Ahora, los abuelos de " ?n " son " $?losAbuelos crlf)
    )
)


(defrule abuelo_paterno
    ?elNieto  <- (persona (nombre ?n) (padre ?p) (abuelos $?losAbuelos))
    (persona (nombre ?p) (padre ?a))
    ?elAbuelo <- (persona (nombre ?a) (nietos $?losNietos))
    =>
    (bind ?pos (member$ ?n $?losNietos))
    (if (not ?pos) then
        (bind $?losNietos (insert$ $?losNietos (+(length$ $?losNietos) 1) ?n))
        (modify ?elAbuelo (nietos $?losNietos))
        (printout t "Ahora, los nietos de " ?a " son " $?losNietos crlf)
    )
    (bind ?pos (member$ ?a $?losAbuelos))
    (if (not ?pos) then
        (bind $?losAbuelos (insert$ $?losAbuelos (+(length$ $?losAbuelos) 1) ?a))
        (modify ?elNieto (abuelos $?losAbuelos))
        (printout t "Ahora, los abuelos de " ?n " son " $?losAbuelos crlf)
    )
)

(defrule abuela_paterna
    ?elNieto  <- (persona (nombre ?n) (padre ?p) (abuelos $?losAbuelos))
    (persona (nombre ?p) (madre ?a))
    ?elAbuelo <- (persona (nombre ?a) (nietos $?losNietos))
    =>
    (bind ?pos (member$ ?n $?losNietos))
    (if (not ?pos) then
        (bind $?losNietos (insert$ $?losNietos (+(length$ $?losNietos) 1) ?n))
        (modify ?elAbuelo (nietos $?losNietos))
        (printout t "Ahora, los nietos de " ?a " son " $?losNietos crlf)
    )
    (bind ?pos (member$ ?a $?losAbuelos))
    (if (not ?pos) then
        (bind $?losAbuelos (insert$ $?losAbuelos (+(length$ $?losAbuelos) 1) ?a))
        (modify ?elNieto (abuelos $?losAbuelos))
        (printout t "Ahora, los abuelos de " ?n " son " $?losAbuelos crlf)
    )
)